{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gs_quant.session import GsSession, Environment\n",
    "from gs_quant.risk import RollFwd\n",
    "from gs_quant.markets.portfolio import Portfolio\n",
    "from gs_quant.instrument import IRSwap, IRSwaption\n",
    "from gs_quant.markets import PricingContext\n",
    "import matplotlib.pyplot as plt\n",
    "import gs_quant.risk as risk\n",
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# external users should substitute their client id and secret; please skip this step if using internal jupyterhub\n",
    "GsSession.use(Environment.PROD, client_id=None, client_secret=None, scopes=('run_analytics',))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a swap which has a 1m floating frequency\n",
    "swap = IRSwap('Pay', '10y', 'EUR', fixed_rate='ATM-5', floating_rate_frequency='1m', name='EUR10y')\n",
    "\n",
    "# resolve the trade as of today to fix the dates and rate\n",
    "swap.resolve()\n",
    "\n",
    "# roll daily for 66 business days assuming both forward curve is realised and spot curve is realised\n",
    "fwd_price = []\n",
    "fwd_cash = []\n",
    "spot_price = []\n",
    "spot_cash = []\n",
    "r = range(0, 66, 6)\n",
    "# by wrapping all the scenarios into one PricingContext we package all the requests into one call to GS\n",
    "with PricingContext():\n",
    "    for bus_days in r:\n",
    "        with PricingContext(is_async=True), RollFwd(date=f'{bus_days}b', holiday_calendar='LDN', realise_fwd=True):\n",
    "            fwd_price.append(swap.price())\n",
    "            fwd_cash.append(swap.calc(risk.Cashflows))\n",
    "        with PricingContext(is_async=True), RollFwd(date=f'{bus_days}b', holiday_calendar='LDN', realise_fwd=False):\n",
    "            spot_price.append(swap.price())\n",
    "            spot_cash.append(swap.calc(risk.Cashflows))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fwd_pv  = pd.Series([p.result() for p in fwd_price], index=r)\n",
    "spot_pv   = pd.Series([p.result() for p in spot_price], index=r)\n",
    "\n",
    "# The output of the cashflows measure is a dataframe of the past and implied future cashflows. We could filter by payment date\n",
    "# but conviently the discount factor is 0 for paid cashflows\n",
    "cash_fwd = pd.Series([c.result()[c.result().discount_factor == 0].payment_amount.sum() for c in fwd_cash], index=r)\n",
    "cash_spot = pd.Series([c.result()[c.result().discount_factor == 0].payment_amount.sum() for c in spot_cash], index=r)\n",
    "\n",
    "fwd_pv.plot(figsize=(10, 6), title='Swap Carry', label='{} Realise Fwd'.format(swap.name))\n",
    "spot_pv.plot(label='{} Realise Spot'.format(swap.name))\n",
    "(fwd_pv+cash_fwd).plot(label='{} Realise Fwd (inc. cash)'.format(swap.name))\n",
    "(spot_pv+cash_spot).plot(label='{} Realise Spot (inc. cash)'.format(swap.name))\n",
    "\n",
    "plt.xlabel('Business Days from Pricing Date')\n",
    "plt.ylabel('PV')\n",
    "plt.legend()\n",
    "plt.show()\n",
    "# note that the steps represent the move in MTM as the cashflows are paid.  The libor fixing is implied from the fwd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "itm_swaption = IRSwaption('Receive', '10y', 'EUR', strike='ATM+20', expiration_date='1m', name='ITM swaption')\n",
    "otm_swaption = IRSwaption('Receive', '10y', 'EUR', strike='ATM-20', expiration_date='1m', name='OTM swaption')\n",
    "port = Portfolio([itm_swaption, otm_swaption])\n",
    "port.resolve()\n",
    "\n",
    "# roll daily for 44 business days assuming both forward curve is realised and spot curve is realised\n",
    "fwd_results = []\n",
    "spot_results = []\n",
    "r = range(0, 44, 4)\n",
    "# by wrapping all the scenarios into one PricingContext we package all the requests into one call to GS\n",
    "with PricingContext():\n",
    "    for bus_days in r:\n",
    "        with PricingContext(is_async=True), RollFwd(date=f'{bus_days}b', holiday_calendar='LDN', realise_fwd=True):\n",
    "            fwd_results.append(port.price())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame.from_records([[p['ITM swaption'], p['OTM swaption']] for p in fwd_results], index=r, columns=['ITM', 'OTM'])\n",
    "df.plot(figsize=(10,6), secondary_y=['OTM'], title='Swaption Carry', xlabel='Business Days', ylabel='PV')\n",
    "# note that the OTM swaption prices at 0 post expiry whereas the ITM swaption prices at the value of the swap."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "metadata": {
     "collapsed": false
    },
    "source": []
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
